using System;
using System.Collections;
using System.Html;
using System.Runtime.CompilerServices;
using Awaiter;
using Nsb;
using Nsb.Classes;
using ThemeChain;
using WhirliGigEdit.Classes;
using jQueryApi;

namespace WhirliGigAdmin
{
    [IgnoreNamespace]
    public static class GigAdmin
    {
        private static bool _publishedHomeExists;

        [PreserveName, PreserveCase]
        public static void Page()
        {
            jQuery.Select("#Account li").First().Html(ThemeYoshi.Email);
            jQuery.Select("#SpaceAdmin").Html(Strings.ParaCase(ThemeBase.BaseName) + " Space Commander");

            jQuery.Select("a.UserLink:contains(Publish pages)").Attribute("title", "publish pages for public viewing");
            jQueryObject goToPages = jQuery.Select("a.UserLink:contains(Go to published pages)").Plugin<Jewl>().DisableLink(true, "no pages are currently published");

            new Await()
                .AddAw(FileBlobBase.ExistsAw, Uri.Join("../pages", ThemeYoshi.DefaultPageName + ".html"))
                .AddDx(delegate(Await aw) { _publishedHomeExists = (bool) aw.Result; })
                .AddDx(delegate { if (_publishedHomeExists) goToPages.Plugin<Jewl>().DisableLink(false, "go to published home page"); })
                .Commit();
        }

        [PreserveName, PreserveCase]
        public static void PublishPages()
        {
            new Await()
                .LoadScript(Uri.Scripts("Scripts/WhirliGigEdit.js"))
                .AddDx(delegate { Publish.PublishEv(null); })
                .Commit();
        }

        [PreserveName, PreserveCase]
        public static void ToPublished()
        {
            if (!_publishedHomeExists)
            {
                Ask.Ok("No files are published.");
                return;
            }
            Storage.SetLocal(ThemeYoshi.CuratingKey, false);
            Window.Location.Href = Uri.Join("pages", ThemeYoshi.DefaultPageName + ".html");
        }

        [PreserveName, PreserveCase]
        public static void ChangeEmail()
        {
            new Await()
                .AddAw(new Ask().TextAw, new Dictionary("Msg", "New email address",
                    "Verify", (ActionB)delegate(object v)
                                       {
                                           string vv = ((string) v).Trim();
                                           if (!Rx.EmailFilter.Test(vv))
                                           {
                                               Ask.Ok("please supply a valid email address");
                                               return false;
                                           }
                                           return true;
                                       }))
                .AddAw(DomElement.RequireResultAw, DomElement.NotFailOrEmpty)
                .AddDx(delegate(Await aw) { aw["newEmail"] = ((string)aw.Result).Trim(); })
                .AddAw(ChangeAccountInfoAw)
                .Commit();
        }

        [PreserveName, PreserveCase]
        public static void ChangePassword()
        {
            jQueryObject html = jQuery.FromHtml("<div class='ChangeAccount'/>");

            jQueryObject password1 = jQuery.FromHtml("<input type='password'/>")
                .AppendTo(html)
                .Before("current<br>")
                ;

            jQueryObject password2 = jQuery.FromHtml("<input type='password'/>")
                .AppendTo(html)
                .Before("<br>new<br>")
                ;

            jQueryObject password3 = jQuery.FromHtml("<input type='password'/>")
                .AppendTo(html)
                .Before("<br>new again<br>")
                ;

            new Await()
                .AddAw(new Ask().OkCancelAw, new Dictionary("Msg", "Change curating password", "Html", html,
                    "Verify", (ActionB) delegate
                              {
                                  if (password1.GetValue() != (string)Storage.GetLocal(ThemeYoshi.CuratePasswordKey))
                                  {
                                      Ask.Ok("incorrect password");
                                      return false;
                                  }
                                  if (String.IsNullOrEmpty(password2.GetValue().Trim()))
                                  {
                                      Ask.Ok("please supply a new password");
                                      return false;
                                  }
                                  if (password2.GetValue() != password3.GetValue())
                                  {
                                      Ask.Ok("new passwords don't match");
                                      return false;
                                  }
                                  if (password2.GetValue().Length < 8)
                                  {
                                      Ask.Ok("new password must be at least 8 characters");
                                      return false;
                                  }
                                  return true;
                              }))
                .AddAw(DomElement.RequireResultAw, DomElement.NotFail)
                .AddDx(delegate(Await aw) { aw["newPassword"] = password2.GetValue(); })
                .AddAw(ChangeAccountInfoAw)
                .AddDx(delegate(Await aw) { Storage.SetLocal(ThemeYoshi.CuratePasswordKey, aw["newPassword"]); })
                .Commit();
        }

        private static void ChangeAccountInfoAw(Await awp)
        {
            Cluster.Spinner(true, .35);

            Dictionary args = new Dictionary();
            args["password"] = Storage.GetLocal(ThemeYoshi.CuratePasswordKey);
            if (awp["newPassword"] != null)
                args["newPassword"] = awp["newPassword"];
            if (awp["newEmail"] != null)
                args["newEmail"] = awp["newEmail"];

            jQueryAjaxOptions options = new jQueryAjaxOptions();
            options.Url = Uri.App("account.php");
            options.DataType = "json";
            options.Data = args;
            options.Type = "GET";

            options.Success =
                delegate(object data, string textStatus, jQueryXmlHttpRequest request1)
                {
                    Cluster.Spinner(false);
                    PkgResult pr = (PkgResult) data;
                    try
                    {
                        if (pr.result)
                            ThemeYoshi.ReloadPage();
                    }
                    catch (Exception e)
                    {
                        options.Error(request1, "account update failed", e);
                        return;
                    }

                    awp.Done();
                };

            options.Error =
                delegate(jQueryXmlHttpRequest request, string textStatus, Exception error)
                {
                    Cluster.Spinner(false);
                    Inform.Error(String.Format("Error updating account {0} {1}", textStatus, error));
                    awp.Handle(new Exception(Exceptions.BlobLoadError));
                };
            jQuery.Ajax(options);
        }
    }
}
